package deconstruction.common;

import java.io.InputStream;
import java.net.URL;
import java.util.Properties;
import java.util.logging.Level;

import net.minecraftforge.common.Configuration;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.registry.LanguageRegistry;

public class UpdateHandler implements Runnable {
    private static UpdateHandler instance = new UpdateHandler();
        public static String latestVersion = "[VERSION NOT FOUND]";
        public final static String REMOTE_VERSION_XML_FILE = "http://pastebin.com/raw.php?i=eZKkKxFX";

         
            // All possible results of the remote version number check
            public static final byte UNINITIALIZED = 0;
            public static final byte CURRENT = 1;
            public static final byte OUTDATED = 2;
            public static final byte ERROR = 3;
            public static final byte FINAL_ERROR = 4;
            public static final byte MC_VERSION_NOT_FOUND = 5;

            // Var to hold the result of the remote version check, initially set to uninitialized
            private static byte result = UNINITIALIZED;
            public static String remoteVersion = null;
            public static String remoteUpdateLocation = null;   
            public static Properties remoteVersionProperties = new Properties();

        
        public static void checkVersion(){
                InputStream remoteVersionRepoStream = null;
        result = UNINITIALIZED;
       
        try {
            URL remoteVersionURL = new URL(REMOTE_VERSION_XML_FILE);
            remoteVersionRepoStream = remoteVersionURL.openStream();
            remoteVersionProperties.loadFromXML(remoteVersionRepoStream);

            String remoteVersionProperty = remoteVersionProperties.getProperty(Loader.instance().getMCVersionString());

            if (remoteVersionProperty != null) {
                String[] remoteVersionTokens = remoteVersionProperty.split("\\|");

                if (remoteVersionTokens.length >= 2) {
                    remoteVersion = remoteVersionTokens[0];
                    remoteUpdateLocation = remoteVersionTokens[1];
                }
                else {
                    result = ERROR;
                }

                if (remoteVersion != null) {
                    if (!Info.LAST_DISCOVERED_VERSION.equalsIgnoreCase(remoteVersion)) {
                        Info.LAST_DISCOVERED_VERSION = remoteVersion;
                    }

                   if (remoteVersion.equalsIgnoreCase(getVersionForCheck())) {
                       result = CURRENT;
                  }
                    else {
                        result = OUTDATED;
                    }
                }

            }
            else {
                result = MC_VERSION_NOT_FOUND;
            }
        }
        catch (Exception e) {
        }
        finally {
            if (result == UNINITIALIZED) {
                result = ERROR;
            }

            try {
                if (remoteVersionRepoStream != null) {
                    remoteVersionRepoStream.close();
                }
            }
            catch (Exception ex) {
            }
        }
    }
        
        
         private static String getVersionForCheck() {

                String[] versionTokens = Info.VERSION.split(" ");

                if (versionTokens.length >= 1)
                    return versionTokens[0];
                else
                    return Info.VERSION;
            }

            public static void logResult() {

                if (result == CURRENT || result == OUTDATED) {
                    Info.log.log(Level.INFO, getResultMessage());
                }
                else {
                    Info.log.log(Level.WARNING, getResultMessage());
                }
            }

            public static String getResultMessage() {

                if (result == UNINITIALIZED)
                    return Info.UNINITIALIZED_MESSAGE;
                else if (result == CURRENT) {
                    String returnString = Info.CURRENT_MESSAGE;
                    returnString = returnString.replace("@REMOTE_MOD_VERSION@", remoteVersion);
                    returnString = returnString.replace("@MINECRAFT_VERSION@", Loader.instance().getMCVersionString());
                    return returnString;
                }
                else if (result == OUTDATED && remoteVersion != null && remoteUpdateLocation != null) {
                    String returnString = Info.OUTDATED_MESSAGE;
                    returnString = returnString.replace("@MOD_NAME@", Info.MOD_ID);
                    returnString = returnString.replace("@REMOTE_MOD_VERSION@", remoteVersion);
                    returnString = returnString.replace("@MINECRAFT_VERSION@", Loader.instance().getMCVersionString());
                    returnString = returnString.replace("@MOD_UPDATE_LOCATION@", remoteUpdateLocation);
                    return returnString;
                }
                else if (result == OUTDATED && remoteVersion != null && remoteUpdateLocation != null) {
                    String returnString = Info.OUTDATED_MESSAGE;
                    returnString = returnString.replace("@MOD_NAME@", Info.MOD_ID);
                    returnString = returnString.replace("@REMOTE_MOD_VERSION@", remoteVersion);
                    returnString = returnString.replace("@MINECRAFT_VERSION@", Loader.instance().getMCVersionString());
                    returnString = returnString.replace("@MOD_UPDATE_LOCATION@", remoteUpdateLocation);
                    return returnString;
                }
                else if (result == ERROR)
                    return Info.GENERAL_ERROR_MESSAGE;
                else if (result == FINAL_ERROR)
                    return Info.FINAL_ERROR_MESSAGE;
                else if (result == MC_VERSION_NOT_FOUND) {
                    String returnString =Info.MC_VERSION_NOT_FOUND;
                    returnString = returnString.replace("@MOD_NAME@", Info.MOD_ID);
                    returnString = returnString.replace("@MINECRAFT_VERSION@", Loader.instance().getMCVersionString());
                    returnString = returnString.replace("@ATTEMPTS@", Integer.toString(Info.VERSION_CHECK_ATTEMPTS));
                    return returnString;
                }
                else {
                    result = ERROR;
                    return Info.GENERAL_ERROR_MESSAGE;
                }
            }

            public static String getResultMessageForClient() {

                String returnString = Info.OUTDATED_MESSAGE;
                returnString = returnString.replace("@MOD_NAME@", Colors.TEXT_COLOUR_PREFIX_YELLOW + Info.NAME + Colors.TEXT_COLOUR_PREFIX_WHITE);
                returnString = returnString.replace("@REMOTE_MOD_VERSION@", Colors.TEXT_COLOUR_PREFIX_YELLOW + UpdateHandler.remoteVersion + Colors.TEXT_COLOUR_PREFIX_WHITE);
                returnString = returnString.replace("@MINECRAFT_VERSION@", Colors.TEXT_COLOUR_PREFIX_YELLOW + Loader.instance().getMCVersionString() + Colors.TEXT_COLOUR_PREFIX_WHITE);
                returnString = returnString.replace("@MOD_UPDATE_LOCATION@", Colors.TEXT_COLOUR_PREFIX_YELLOW + UpdateHandler.remoteUpdateLocation + Colors.TEXT_COLOUR_PREFIX_WHITE);
                return returnString;
            }

            public static byte getResult() {

                return result;
            }

            @Override
            public void run() {

                int count = 0;

                Info.log.log(Level.INFO, Info.VERSION_CHECK_INIT_LOG_MESSAGE + " " + REMOTE_VERSION_XML_FILE);

                try {
                    while (count < Info.VERSION_CHECK_ATTEMPTS - 1 && (result == UNINITIALIZED || result == ERROR)) {

                        checkVersion();
                        count++;
                        logResult();

                        if (result == UNINITIALIZED || result == ERROR) {
                            Thread.sleep(10000);
                        }
                    }

                    if (result == ERROR) {
                        result = FINAL_ERROR;
                        logResult();
                    }
                }
                catch (InterruptedException e) {
                }

            }

            public static void execute() {

                new Thread(instance).start();
            }

        }